package cn.imvc.app.controllers;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.druid.util.StringUtils;
import com.github.sd4324530.fastweixin.api.JsAPI;
import com.github.sd4324530.fastweixin.api.MenuAPI;
import com.github.sd4324530.fastweixin.api.OauthAPI;
import com.github.sd4324530.fastweixin.api.QrcodeAPI;
import com.github.sd4324530.fastweixin.api.entity.Menu;
import com.github.sd4324530.fastweixin.api.entity.MenuButton;
import com.github.sd4324530.fastweixin.api.enums.MenuType;
import com.github.sd4324530.fastweixin.api.enums.QrcodeType;
import com.github.sd4324530.fastweixin.api.enums.ResultType;
import com.github.sd4324530.fastweixin.api.response.BaseResponse;
import com.github.sd4324530.fastweixin.api.response.GetSignatureResponse;
import com.github.sd4324530.fastweixin.api.response.GetUserInfoResponse;
import com.github.sd4324530.fastweixin.api.response.OauthGetTokenResponse;
import com.github.sd4324530.fastweixin.api.response.QrcodeResponse;
import com.github.sd4324530.fastweixin.util.JSONUtil;
import com.github.sd4324530.fastweixin.util.NetWorkCenter;

import cn.imvc.app.commons.SystemConfig;
import cn.imvc.app.domains.Constants;
import cn.imvc.app.entities.Dealer;
import cn.imvc.app.entities.Member;
import cn.imvc.app.models.DealerModel;
import cn.imvc.app.models.MemberModel;
import cn.imvc.core.ICache;
import cn.imvc.core.Render;
import cn.imvc.util.CookieTools;
import cn.imvc.util.SMSVerification;
import cn.imvc.util.ToolUtils;
import cn.imvc.util.Wechat;
import cn.imvc.util.WechatLogin;

@Controller
@RequestMapping("/wechat")
public class WechatControllerImpl implements WechatController {
	private Logger logger = Logger.getLogger(WechatControllerImpl.class);
	@Autowired
	ICache cache;
	@Autowired
	Wechat wechat;
	@Autowired
	WechatLogin wechatLogin;

	@Autowired
	MemberModel memberModel;
	
	@Autowired
	SystemConfig systemConfig;
	
	@Autowired
	DealerModel dealerModel;

	@Autowired
	SMSVerification smsVerification;

	@RequestMapping("/auth.html")
	public void auth(String code, String state, String url, String domain, HttpServletRequest request, HttpServletResponse response) {

		if (code == null || code.isEmpty()) {// 用户取消授权
			try {
				response.sendRedirect("http://www.xinghaoshangcheng.com" + url);
				response.flushBuffer();
				return;
			
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (code != null && state != null && state.equals("authAop")) {
			OauthAPI oauth = new OauthAPI(wechat.getApiConfig());
			OauthGetTokenResponse OauthToken = oauth.getToken(code);
			if (OauthToken != null)
				if (OauthToken.getAccessToken() != null && OauthToken.getOpenid() != null) {
					String[] www = domain.split("\\.");
					if (www.length == 3 && !"www".equals(www[0])) {
						Dealer dealer = dealerModel.getByDomain(www[0]);
						if (dealer != null) {
							cache.put("SCAN", OauthToken.getOpenid(), dealer.getMember());
						}
					}
					logger.info(OauthToken.getOpenid() + ":" + ToolUtils.getDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss"));
					CookieTools.addCookie(response, "user_access_token", Constants.DOMAIN_SUFFIX.substring(1), OauthToken.getAccessToken(), 7000);
					cache.putSecond("WEIXIN_CACHE", OauthToken.getAccessToken(), OauthToken.getOpenid(), 7000);
					GetUserInfoResponse userInfoResponse = oauth.getUserInfo(OauthToken.getAccessToken(), OauthToken.getOpenid());
					String openId = OauthToken.getOpenid();
					cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "uid", userInfoResponse.getUnionid(), 7000);
					cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "name", userInfoResponse.getNickname(), 7000);
					cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "himg", userInfoResponse.getHeadimgurl(), 7000);
					Member member = memberModel.findByUnionid(userInfoResponse.getUnionid());
					if(member != null){
						String wxOpenId = member.getWxOpenid();
						if(wxOpenId==null || StringUtils.isEmpty(wxOpenId) || wxOpenId.startsWith("oHkkmw")){
							member.setWxOpenid(OauthToken.getOpenid());
							memberModel.save(member);
						}
					}
				}
		}
		try {
			response.sendRedirect("http://www.xinghaoshangcheng.com" + url);
			response.flushBuffer();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("/reglogin.html")
	public String reglogin(String url, Model model, String type, String domain, HttpServletRequest request) {
		model.addAttribute("url", url);
		model.addAttribute("type", type);
		model.addAttribute("domain", domain);
		String ip = ToolUtils.getIpAddress(request);
		Integer ipTimes = cache.get(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip);
		if(ipTimes != null && ipTimes >= smsVerification.getIpTimes()){
			model.addAttribute("showImageCode", true);
		} else {
			model.addAttribute("showImageCode", false);
		}
		return "wechat/reglogin";
	}

	@RequestMapping("/reglogin.htm")
	public String pcreglogin(Model model, String type, HttpServletRequest request) {
		model.addAttribute("type", type);
		String ip = ToolUtils.getIpAddress(request);
		Integer ipTimes = cache.get(Constants.CACHENAME_MEMBER, "IP_TIMES_" + ip);
		if(ipTimes != null && ipTimes >= smsVerification.getIpTimes()){
			model.addAttribute("showImageCode", true);
		} else {
			model.addAttribute("showImageCode", false);
		}
		return "wechat/pcreglogin";
	}

	@RequestMapping("/regloginsubmit.html")
	@ResponseBody
	public String regloginsubmit(String mobile, String code, String type, String domain, HttpServletRequest request, HttpServletResponse response, Model model) {
		String serverName = request.getServerName();
		GetUserInfoResponse userInfoResponse = new GetUserInfoResponse();
		Map<String, String> map = new HashMap<String,String>();
		// type：null或者qq，请求来自app或者pc端；open，请求来自微信公众号
		if(StringUtils.isEmpty(type) || "open".equals(type)){
			Cookie userAccessToken = CookieTools.getCookieByName(request, "user_access_token");
			if(userAccessToken == null){
				map.put("code", "0");
				map.put("msg", "授权信息已过期，请重新授权");
				return Render.json(map);
			}
			String openid = cache.getSecond("WEIXIN_CACHE", userAccessToken.getValue());
			String uid = cache.getSecond("WEIXIN_CACHE_USERINFO", openid + "uid");
			if(StringUtils.isEmpty(uid)){
				map.put("code", "0");
				map.put("msg", "授权信息已过期，请重新授权");
				return Render.json(map);
			}
			String name = cache.getSecond("WEIXIN_CACHE_USERINFO", openid + "name");
			String himg = cache.getSecond("WEIXIN_CACHE_USERINFO", openid + "himg");
			userInfoResponse.setUnionid(uid);
			userInfoResponse.setNickname(name);
			userInfoResponse.setHeadimgurl(himg);
			// 微信公众号的openid保存到member的wxopenid字段
			if("open".equals(type)){
				map = memberModel.saveRegLoginSubmit(mobile, code, openid, userInfoResponse, type, domain, serverName);
			} else {
				map = memberModel.saveRegLoginSubmit(mobile, code, null, userInfoResponse, type, domain, serverName);
			}
		} else if ("qq".equals(type)) {
			Cookie userAccessToken = CookieTools.getCookieByName(request, "qquser_access_token");
			if(userAccessToken == null){
				map.put("code", "0");
				map.put("msg", "授权信息已过期，请重新授权");
				return Render.json(map);
			}
			String openid = cache.getSecond("QQ_CACHE", userAccessToken.getValue());
			if(StringUtils.isEmpty(openid)){
				map.put("code", "0");
				map.put("msg", "授权信息已过期，请重新授权");
				return Render.json(map);
			}
			String name = cache.getSecond("QQ_CACHE_USERINFO", openid + "name");
			String himg = cache.getSecond("QQ_CACHE_USERINFO", openid + "himg");
			userInfoResponse.setUnionid(openid);
			userInfoResponse.setNickname(name);
			userInfoResponse.setHeadimgurl(himg);
			map = memberModel.saveRegLoginSubmit(mobile, code, null, userInfoResponse, type, domain, serverName);
		} else {
			map.put("code", "0");
			map.put("msg", "系统异常，请稍后再试");
		}
		return Render.json(map);
	}

	@RequestMapping("/qr.html")
	public void qr(HttpServletRequest request, HttpServletResponse response) {

		QrcodeAPI qrcode=new QrcodeAPI(wechat.getApiConfig());
		
		wechat.getAppId();
		
		
		JsAPI jsapi = new JsAPI(wechat.getJsApiConfig());
		GetSignatureResponse jsconfig = jsapi.getSignature("");
		
		//永久二维码 只有顶级分销商拥有
		QrcodeResponse qrcodeResponse=qrcode.createQrcode(QrcodeType.QR_LIMIT_SCENE, "1-100000", 2592000);
		
		//临时二维码sceneId 为用户id
		QrcodeResponse qrcodeResponse2=qrcode.createQrcode(QrcodeType.QR_SCENE, "11212", 2592000);
		//二维码地址
		qrcodeResponse2.getUrl();
		///https://mp.weixin.qq.com/wiki/18/167e7d94df85d8389df6c94a7a8f78ba.html  微信文档
	}
	@RequestMapping("/changeMenu.html")
	@ResponseBody
	public String changeMenu(HttpServletRequest request, HttpServletResponse response) {

		MenuAPI menuapi = new MenuAPI(wechat.getApiConfig());
		Menu menu = new Menu();
		
		List<MenuButton> button = new ArrayList<MenuButton>();
		MenuButton mbutton = new MenuButton();		
		mbutton.setName("商城入口");
		mbutton.setType(MenuType.VIEW);
		mbutton.setUrl("http://www.xinghaoshangcheng.com/index.jsp");
		button.add(mbutton);
		
		MenuButton mbutton2 = new MenuButton();		
		mbutton2.setName("个人中心");
		mbutton2.setType(MenuType.VIEW);
		mbutton2.setUrl("http://www.xinghaoshangcheng.com/center/center.html");
		button.add(mbutton2);
		
		MenuButton mbutton3 = new MenuButton();		
		mbutton3.setName("关于星昊");
		mbutton3.setType(MenuType.VIEW);
		mbutton3.setUrl("http://www.xinghaoshangcheng.com/article/home.html");
		button.add(mbutton3);
		
		menu.setButton(button);
		ResultType rt = menuapi.createMenu(menu);

		return Render.text(rt.toString());
	}

	/**
	 * PC端微信扫码登陆
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/login.htm")
	public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String url = Constants.DOMAIN + "/wechat/check.html";
		try {
			url = URLEncoder.encode(url, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			logger.error("URL编码出错", e);
		}
		StringBuilder stringBuilder = new StringBuilder("https://open.weixin.qq.com/connect/qrconnect?");
		stringBuilder.append("appid=").append(wechatLogin.getPcAppId()).append("&redirect_uri=").append(url)
				.append("&response_type=code&scope=snsapi_login").append("&state=").append("pc").append("#wechat_redirect");
		response.sendRedirect(stringBuilder.toString());
	}

	/**
	 * 用户授权登陆注册
	 * @param code
	 * @param state
	 * @param request
	 * @param response
	 */
	@RequestMapping("/check.html")
	public void check(String code, String state, String domain, HttpServletRequest request, HttpServletResponse response) {
		String url = "";
		if(!StringUtils.isEmpty(state)){
			if("app".equals(state)){
				url = Constants.DOMAIN + "/member/login.html";
			} else if("pc".equals(state)) {
				url = Constants.DOMAIN + "/member/login.htm";
			}
		}
		if (code == null || code.isEmpty()) {// 用户取消授权
			try {
				response.sendRedirect(url);
				response.flushBuffer();
				return;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (code != null && state != null) {
			OauthGetTokenResponse oresponse = null;
			String wxurl ="";
			if("app".equals(state)){
				 wxurl ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wechatLogin.getAppId() + "&secret=" + wechatLogin.getAppSecret() + "&code=" + code + "&grant_type=authorization_code";
			} else if("pc".equals(state)) {
				 wxurl ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wechatLogin.getPcAppId() + "&secret=" + wechatLogin.getPcAppSecret() + "&code=" + code + "&grant_type=authorization_code";
			        
			}
			
			BaseResponse r = NetWorkCenter.get(wxurl);
			
			String resultJson = ResultType.SUCCESS.getCode().toString().equals(r.getErrcode())  ? r.getErrmsg() : r.toJsonString();
	        oresponse = JSONUtil.toBean(resultJson, OauthGetTokenResponse.class);
			
			OauthGetTokenResponse OauthToken =oresponse;
			if (OauthToken != null){
				String token = OauthToken.getAccessToken();
				if (token != null && OauthToken.getOpenid() != null) {
					String uid = OauthToken.getUnionid();
					Member member = memberModel.findByUnionid(uid);
					if(member != null){
						CookieTools.addCookie(response, "token", Constants.DOMAIN_SUFFIX.substring(1), token, Constants.TOKEN_INDATE);
						cache.put(Constants.CACHENAME_MEMBER, token, member, Constants.TOKEN_INDATE);
						if("app".equals(state)){
							url = Constants.DOMAIN + "/index.html";
						} else if("pc".equals(state)) {
							String domainUrl = Constants.DOMAIN;
							if(member.getDealer() != null){
								String dealer_domain = member.getDealer().getDomain();
								if(StringUtils.isEmpty(dealer_domain)){
									dealer_domain = "www";
								}
								domainUrl = Constants.DOMAIN_PREFIX + dealer_domain + Constants.DOMAIN_SUFFIX;
							}
							url = domainUrl + "/index.htm";
						}
					} else {
						CookieTools.addCookie(response, "user_access_token", Constants.DOMAIN_SUFFIX.substring(1), OauthToken.getAccessToken(), 7000);
						cache.putSecond("WEIXIN_CACHE", OauthToken.getAccessToken(), OauthToken.getOpenid(), 7000);

					    GetUserInfoResponse userInfoResponse = null;
				        String urluserinfo = "https://api.weixin.qq.com/sns/userinfo?access_token=" + OauthToken.getAccessToken() + "&openid=" +  OauthToken.getOpenid() + "&lang=zh_CN";
				        BaseResponse userinforesponse = NetWorkCenter.get(urluserinfo);
				        resultJson = ResultType.SUCCESS.getCode().toString().equals(userinforesponse.getErrcode())  ? userinforesponse.getErrmsg() : userinforesponse.toJsonString();
				        userInfoResponse = JSONUtil.toBean(resultJson, GetUserInfoResponse.class);

						String openId = OauthToken.getOpenid();
						cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "uid", userInfoResponse.getUnionid(), 7000);
						cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "name", userInfoResponse.getNickname(), 7000);
						cache.putSecond("WEIXIN_CACHE_USERINFO", openId + "himg", userInfoResponse.getHeadimgurl(), 7000);
						if("app".equals(state)){
							url = Constants.DOMAIN + "/wechat/reglogin.html?domain=" + domain;
						} else if("pc".equals(state)) {
							url = Constants.DOMAIN + "/wechat/reglogin.htm?domain=" + domain;
						}
					}
				}
			}
		}
		try {
			response.sendRedirect(url);
			response.flushBuffer();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

}
